package com.yx.modules.api.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.qq.connect.QQConnectException;
import com.qq.connect.api.OpenID;
import com.yx.OpenIDOAuth.weibo.src.weibo4j.Oauth;
import com.yx.OpenIDOAuth.weibo.src.weibo4j.http.AccessToken;
import com.yx.OpenIDOAuth.weibo.src.weibo4j.model.WeiboException;
import com.yx.common.utils.R;
import com.yx.common.validator.Assert;
import com.yx.modules.api.annotation.AuthIgnore;
import com.yx.modules.api.annotation.LoginUser;
import com.yx.modules.api.entity.TbGradeRecord;
import com.yx.modules.api.entity.TbUser;
import com.yx.modules.api.service.TbGradeRecordService;
import com.yx.modules.api.service.TbTokenService;
import com.yx.modules.api.service.TbUserService;
import com.yx.pay.alipay.AlipayConfig;
import com.yx.system.entity.TdOnlinePayLog;
import com.yx.system.entity.TdOrder;
import com.yx.system.entity.TdWalletPayLog;
import com.yx.system.service.TdOnlinePayLogService;
import com.yx.system.service.TdOrderService;
import com.yx.system.service.TdWalletPayLogService;
import com.yx.utils.*;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

/**
 * 用户会员控制器
 */
@RestController
@RequestMapping("/api/user")
public class UserInfoController {

    @Autowired
    private TbUserService tbUserService;

    @Autowired
    private TbTokenService tbTokenService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private TbTokenService tokenService;

    @Autowired
    private TdOrderService tdOrderService;

    @Autowired
    private TdWalletPayLogService tdWalletPayLogService;

    @Autowired
    private TdOnlinePayLogService tdOnlinePayLogService;

    @Autowired
    private TbGradeRecordService tbGradeRecordService;

    /**
     * 按UID查询用户
     *
     * @return
     */
    @PostMapping("findByUid")
    public R findByUId(String uid) {
        TbUser tbUser = tbUserService.queryByUid(uid);
        tbUser.setQqopenid("");
        tbUser.setQqtoken("");
        tbUser.setWbtoken("");
        tbUser.setWbopenid("");
        tbUser.setPassword("");
        tbUser.setEnabled(null);
        tbUser.setUserId(null);
        return R.ok().put("user", tbUser);
    }

    /*
   * 获取用户对书籍打分
   */
    @RequestMapping("/grade")
    public R getGrade(Integer bookid,@LoginUser TbUser tbUser){
        Assert.isNull(bookid,"图书不能传空");
        TbGradeRecord tbGradeRecord = tbGradeRecordService.findByUserIdAndBookId(tbUser.getUserId(),bookid);
        return R.ok().put("data",tbGradeRecord);
    }

    /**
     * 更新
     *
     * @return
     */
    @PostMapping("update")
    public R update(Long id, String profileimageurl, String nickname, Boolean sex, String description) {
        TbUser tbUser = tbUserService.foundById(id);
        tbUser.setNickname(nickname);
        tbUser.setDescription(description);
        tbUser.setSex(sex);
        tbUser.setProfileimageurl(profileimageurl);
        return R.ok().put("user", tbUserService.updateById(tbUser));
    }

    /**
     * 注销
     *
     * @return
     */
    @PostMapping("UnCancellation")
    public R UnCancellation(@LoginUser TbUser tbUser) {
        tbTokenService.createToken(tbUser.getUserId());
        return R.ok();
    }

    /**
     * 阿里支付
     *
     * @return
     */
    @PostMapping("alipay")
    public R alipay(@LoginUser TbUser tbUser, String money) {
        System.out.print("alipay");
        String orderNo = OrderUtil.getOrderNo2();
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.app_id, AlipayConfig.merchant_private_key, null, AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //获得初始化的AlipayClient
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);//在公共参数中设置回跳和通知地址
        alipayRequest.setBizContent("{" +
                "    \"out_trade_no\":" + orderNo + "," +
                "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                "    \"total_amount\":" + money + "," +
                "    \"subject\":\"余额充值\"," +
                "    \"body\":\"余额充值\"," +
                "    \"passback_params\":\"\"," +
                "    \"extend_params\":{}" +
                "  }");//填充业务参数
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
//            httpResponse.getWriter().write("<html><body>" + form + "</body></html>");//直接将完整的表单html输出到页面
//            httpResponse.getWriter().flush();
//            httpResponse.getWriter().close();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        TdOrder order = new TdOrder();
        order.setUuid(tbUser.getUuid());
        //为订单赋值
        order.setBillno(orderNo);
        order.setBookid(null);
        order.setCreatedate(new Date());
        order.setTotalfee(Integer.parseInt(AmountUtils.changeY2F(money)));
        order.setUsername(tbUser.getUsername());
        order.setUserphone(tbUser.getMobile());
        order.setSectionid(null);
        order.setOrderstatus(PayStatus.unpaid.getName());
        order.setIspay(false);
        order.setPaytype(PayType.ALI_WEB.getName());
        order.setCreateuser(tbUser.getUsername());
        order.setYear(DateUtil.getYear(new Date()));
        order.setMonth(DateUtil.getMonth(new Date()));
        order.setDay(DateUtil.getDay(new Date()));
        tdOrderService.insert(order);
        //存入支付数据
        TdOnlinePayLog opl = new TdOnlinePayLog();
        opl.setCreatedate(new Date());
        opl.setBillno(orderNo);
        opl.setCreateuser(tbUser.getUsername());
        opl.setUuid(UUIDUtil.getUUID());
        opl.setUserid(tbUser.getUserId() + "");
        opl.setPaytype(order.getPaytype());
        opl.setTitle("余额充值");
        opl.setTotalfee(order.getTotalfee());
        opl.setPaystatus(PayStatus.unpaid.getName());
        opl.setWebhookstatus(PayStatus.unpaid.getName());
        opl.setUserpaystatus(PayType.ALI_WEB.getName());
        tdOnlinePayLogService.insert(opl);

        TdWalletPayLog twp = new TdWalletPayLog();
        twp.setBillno(orderNo);
        twp.setCreatedate(new Date());
        twp.setCreateuser(tbUser.getUsername());
        twp.setPaystatus(PayStatus.unpaid.getName());
        twp.setReturntype(PayStatus.unpaid.getName());
        twp.setTitle("余额充值");
        twp.setTotalfee(Integer.parseInt(AmountUtils.changeY2F(money)));
        twp.setUserpaystatus("PAY_ALIWEB");
        twp.setPaytype("put");
        twp.setUuid(tbUser.getUuid());
        twp.setWebhookstatus(PayStatus.unpaid.getName());
        tdWalletPayLogService.insert(twp);
        return R.ok().put("form", "<html><body>" + form + "</body></html>");

    }

    @AuthIgnore
    @PostMapping("notify_url")
    public void notify_url(@RequestParam Map<String, Object> map) {
        System.out.print("进入回调");
        if (map.get("trade_status".toString()).equals("TRADE_SUCCESS")) {
            String orderNo = map.get("out_trade_no").toString();
            int totalFee = Integer.parseInt(AmountUtils.changeY2F((map.get("total_amount").toString())));
            TdOrder tdOrder = tdOrderService.queryByBillNo(orderNo);
            if (tdOrder != null) {
                TdOnlinePayLog tdOnlinePayLog = tdOnlinePayLogService.queryByBillNo(orderNo);
                TdWalletPayLog tdWalletPayLog = tdWalletPayLogService.queryByBillNo(orderNo);
                if (tdOnlinePayLog.getWebhookstatus().equals(PayStatus.success.getName())) {
                    System.out.println("已经处理过的回调请求，本次直接跳过！");
                } else {
                    if (tdOrder.getTotalfee() == totalFee) {
                        tdOrder.setIspay(true);
                        tdOrder.setPaydate(new Date());
                        tdOrder.setOrderstatus(PayStatus.success.getName());
                        tdOrder.setUpdatedate(new Date());
                        tdOrder.setUpdateuser("sys");
                        tdOrderService.updateByPrimaryKey(tdOrder);

                        //增加用户余额
                        TbUser tbUser = tbUserService.findByMobile(tdOrder.getUserphone());
                        System.out.println("================"+tbUser+"======================");
                        tbUser.setBalance(tbUser.getBalance()+(tdOrder.getTotalfee()*100));

                        tbUserService.update(tbUser);

                        tdOnlinePayLog.setWebhookstatus(PayStatus.success.getName());
                        tdOnlinePayLog.setPaystatus(PayStatus.success.getName());
                        tdOnlinePayLog.setReturntype("notify_url");
                        tdOnlinePayLog.setUpdatedate(new Date());
                        tdOnlinePayLog.setUpdateuser("sys");
                        tdOnlinePayLogService.updateByPrimaryKey(tdOnlinePayLog);

                        tdWalletPayLog.setWebhookstatus(PayStatus.success.getName());
                        tdWalletPayLog.setReturntype("notify_url");
                        tdWalletPayLog.setPaystatus(PayStatus.success.getName());
                        tdWalletPayLog.setUpdatedate(new Date());
                        tdWalletPayLog.setUpdateuser("sys");
                        tdWalletPayLogService.updateByPrimaryKey(tdWalletPayLog);
                    } else {
                        System.out.println("回调的金额与数据库中的金额不一致，本次不处理！");
                    }
                }
            } else {
                System.out.println("订单查询未空！");
            }
        }

    }

    @AuthIgnore
    @GetMapping("return_url")
    public ModelAndView return_url() {
        System.out.print("return_url");
        ModelAndView mv = new ModelAndView("return_url");
        return mv;

    }


    /**
     * 修改密码
     */
    @AuthIgnore
    @PostMapping("updatePassWord")
    public R AuthIgnore(String mobile, String password, String oldpwd) {
        Assert.isBlank(mobile, "手机号不能为空");
        Assert.isBlank(password, "密码不能为空");
        Assert.isBlank(oldpwd, "原密码不能为空");
        TbUser tbUser = tbUserService.queryByMobile(mobile);
        if (tbUser != null) {
            //持久化数据
            if (tbUser.getPassword().equals(DigestUtils.sha256Hex(oldpwd))) {
                tbUser.setPassword(DigestUtils.sha256Hex(password));
                tbUserService.updateById(tbUser);
            } else {
                return R.error("旧密码不正确！");
            }
            return R.ok();
        } else {
            return R.error("未查到该用户！");
        }
    }

    /**
     * 忘记密码
     */
    @AuthIgnore
    @PostMapping("forgetpwd")
    public R forgetpwd(String mobile, String password, String code) {
        Assert.isBlank(mobile, "手机号不能为空");
        Assert.isBlank(password, "密码不能为空");
        Assert.isBlank(code, "验证码不能为空");
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(mobile);
        if (rcode == null) {
            return R.error("验证码过期");
        }
        if (rcode.equals(code)) {
            if (tbUserService.queryByMobile(mobile) != null) {
                TbUser tbUser = tbUserService.queryByMobile(mobile);
                tbUser.setPassword(DigestUtils.sha256Hex(password));
                //持久化数据
                tbUserService.updateById(tbUser);
                return R.ok();
            } else {
                return R.error("未查到该用户！");
            }
        } else {
            return R.error("验证码错误");
        }
    }


    /**
     * 微博回调
     *
     * @param code
     * @return
     */
    @AuthIgnore
    @GetMapping("weboredirect")
    public ModelAndView weboredirect(String code) {
        ModelAndView model = new ModelAndView();
        //1.获取token
        Oauth oauth = new Oauth();
        try {
            AccessToken accessToken = oauth.getAccessTokenByCode(code);
            String wbtoken = accessToken.getAccessToken();
            String wbopenid = accessToken.getUid();
            TbUser tbUser = tbUserService.queryWBBangd(wbtoken, wbopenid);
            if (tbUser == null) {
                model.setViewName("redirect:http://www.youwenyuedu.com/#/LoginFromSNS?type=weiboReg&token=" + accessToken.getAccessToken() + "&uid=" + accessToken.getUid());
            } else {
                //生成token
                Map<String, Object> map = tokenService.createToken(Long.parseLong(tbUser.getUserId() + ""));
                map.put("user", tbUserService.foundById(Long.parseLong(tbUser.getUserId() + "")));
                JSONObject jsonObject = JSONObject.fromObject(map);
                String par = URLEncoder.encode(jsonObject.toString());
                model.setViewName("redirect:http://www.youwenyuedu.com/#/LoginFromSNS?type=login&val=" + par);
            }
        } catch (WeiboException e) {
            e.printStackTrace();
        }
        return model;
    }

    /**
     * QQ回调
     *
     * @return
     */
    @AuthIgnore
    @GetMapping("qqredirect")
    public ModelAndView qqredirect(HttpServletRequest request) {
        ModelAndView model = new ModelAndView();
        request.getSession().setAttribute("qq_connect_state", "web");
        //1.获取token
        // 利用获取到的accessToken 去获取当前用的openid -------- start
        try {
            com.qq.connect.javabeans.AccessToken accessTokenObj = new com.qq.connect.oauth.Oauth().getAccessTokenByRequest(request);
            String accessToken = accessTokenObj.getAccessToken();
            OpenID openIDObj = new OpenID(accessToken);
            String openID = openIDObj.getUserOpenID();
            TbUser tbUser = tbUserService.queryQQBangd(accessToken, openID);
            if (tbUser == null) {
                model.setViewName("redirect:http://www.youwenyuedu.com/#/LoginFromSNS?type=qqReg&token=" + accessToken + "&uid=" + openID);
            } else {
                //生成token
                Map<String, Object> map = tokenService.createToken(Long.parseLong(tbUser.getUserId() + ""));
                map.put("user", tbUserService.foundById(Long.parseLong(tbUser.getUserId() + "")));
                JSONObject jsonObject = JSONObject.fromObject(map);
                String par = URLEncoder.encode(jsonObject.toString());
                model.setViewName("redirect:http://www.youwenyuedu.com/#/LoginFromSNS?type=login&val=" + par);
            }
        } catch (QQConnectException e) {
            e.printStackTrace();
        }
        return model;
    }

    /**
     * 微博注册
     */
    @AuthIgnore
    @PostMapping("snsregister")
    public R register(String mobile, String password, String code, String token, String uid, String type) {
        Assert.isBlank(mobile, "手机号不能为空");
        Assert.isBlank(password, "密码不能为空");
        Assert.isBlank(code, "验证码不能为空");
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(mobile);
        if (rcode == null) {
            return R.error("验证码过期");
        }
        if (rcode.equals(code)) {
            if (tbUserService.queryByMobile(mobile) == null) {
                TbUser user = new TbUser();
                user.setMobile(mobile);
                user.setUsername(mobile);
                user.setPassword(DigestUtils.sha256Hex(password));
                user.setCreateTime(new Date());
                user.setUuid(UidUtil.getUUID());
                user.setSex(true);
                user.setBalance(0);
                user.setDescription("");
                user.setEnabled(true);
                user.setNickname(mobile);
                if (type.equals("weibo")) {
                    user.setWbtoken(token);
                    user.setWbopenid(uid);
                } else {
                    user.setQqopenid(uid);
                    user.setQqtoken(token);
                }
                //持久化数据
                tbUserService.insert(user);
                return R.ok();
            } else {
                return R.error("手机号已经被注册");
            }
        } else {
            return R.error("验证码错误");
        }


    }

    /**
     * 第三方登录绑定
     *
     * @param tbUser 用户信息
     * @param type   类型：weibo、qq
     * @param token  第三方token
     * @param uid    第三方用户唯一标识
     * @return
     */
    @PostMapping("snsbangd")
    public R snsbangd(@LoginUser TbUser tbUser, String type, String token, String uid) {
        if (type.equals("weibo")) {
            tbUser.setWbopenid(uid);
            tbUser.setWbtoken(token);
        } else if (type.equals("qq")) {
            tbUser.setQqtoken(token);
            tbUser.setQqopenid(uid);
        }
        tbUserService.update(tbUser);
        return R.ok();
    }
}
